-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add react-native-web support #3958
Conversation
src/Video.web.tsx
Outdated
return ( | ||
<video | ||
ref={nativeRef} | ||
src={source?.uri as string | undefined} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non URL sources are not supported, I guess there's no way arround it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, but may need a comment in the the doc (even it doesn't really make sense on web I think ... )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onLoad?.({ | ||
currentTime: nativeRef.current.currentTime, | ||
duration: nativeRef.current.duration, | ||
videoTracks: [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HTML5 does not give us tracks info (nor a way to select the current video/audio.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add note in doc :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/Video.web.tsx
Outdated
onVolumeChange?.({volume: nativeRef.current.volume}); | ||
}} | ||
onEnded={onEnd} | ||
style={{position: 'absolute', inset: 0, objectFit: 'contain'}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't use the StyleSheet api since this is a raw html component. Should I simply add a comment to disable the eslint warning here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have the issue if you move the style in a const variable ?
I think it would be better
src/types/video-ref.ts
Outdated
setVolume: (volume: number) => void; | ||
getCurrentPosition: () => Promise<number>; | ||
setFullScreen: (fullScreen: boolean) => void; | ||
nativeHtmlRef?: RefObject<HTMLVideoElement>; // web only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be needed for a user to add custom HTML5 libs (like hls.js, video.js or better subtitles handling).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not document this, if we go into integrating vifdeo.js/shaka/something this would not be needed anymore and then removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zoriya Is it a good idea to expose nativeHtmlRef to the UI ? do it bring some additionnal feature .
maybe you can rename it to nativeHtmlVideoRef it will allow to create new values for shaka / video.js, ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure where to add documentation for this, maybe in the method page? Since it's the page that talk about the video ref?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added it on the method page
I tested that everything works with the I'm thinking that RNV should have more features than the default browsers allow, and integrating HLS/Dash/Ads should not be left for the user. On my project, I'm using HLS.js, srt-webvtt and jassub to have hls/srt/ass support. Maybe we could find an extensible and not too bloaty library to use as a video backend on the web. I'm not familiar with the state of those libs right now but I have heard of video.js and shaka-player. What do you think about integrating one of those libraries @freeboub @KrzysztofMoch? |
@zoriya I agree with you - but let's do it in next (separate) PR I will try to review this PR this week! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested this in our basic
example (with expo web) and it's working very well!
For now are working only mp4
files but support for other let's leave for later. I will look into code now.
Overall grate job @zoriya 🔥
Thanks, I'll correct review comments & rebase during the night! |
src/Video.web.tsx
Outdated
// making the video fullscreen does not work with some subtitles polyfils | ||
// so I decided to not include it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean that some subtitles polyfils are not working when video is in fullscreen ? Users can open fullscreen from UI so I think we can implement those and add warning in docs WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, some subtitles polyfill use a canvas or other HTML elements to draw on top of the video, and those do not work if we simply full-screen the video.
I was thinking of implementing the full-screen feature after adding the polyfill, since it's possible to fullscreen a container of both the video and the polyfill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand, but can we for now implement "built-in" fullscreen? We can later edit it to support subtitles polyfills
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kay, i'll add that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's what I used. Controls can't be shown using this tho.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CleanShot.2024-07-10.at.15.53.00.mp4
I have checked it and it's working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Built-in (HTML5 defaults) controls will show but not custom ones
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see three ways of fixing this:
- have a props for a ref of the item that needs to be in fullscreen (could be a ref to document.body)
- have controls as child of the Video element
- add an html id/class
player-controls
and we could find the closest parent with this class to fullscreen
The second one is the most "react-like" but it kinda breaks expectation of having a simple Video element + it's a breaking.
The other two feels more like escape hatch.
What does the fullscreen behavior does on android/ios? I must say I never used it and always used fullscreen on the whole route via the router.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fullscreen on iOS/Android also doesn't allow custom controls so it's not a problem (maybe in future we will add it)
@zoriya I still 2 documentation comments to handle. + conflicts to fix . And it is good on my side. |
13f77b8
to
6768c22
Compare
@@ -7,4 +7,4 @@ export {default as ResizeMode} from './ResizeMode'; | |||
export {default as TextTrackType} from './TextTrackType'; | |||
export {default as ViewType} from './ViewType'; | |||
export * from './video'; | |||
export * from '../specs/VideoNativeComponent'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was only used for event types so I removed it and added a
export type * from '../spec/VideoNativeComponent';
in the events.ts
file. I assumed the default export was not used, if it's used I can restore it like before and add a file that export a dummy object for the web.
I rebased & added all new properties. Everything should be documented, I missed the |
@zoriya How is this feature? |
what does this mean? The PR just needs to be reviewed again/approved if that was the question |
merge this PR please :) |
What's the expected behavior when using |
Except the Once this get merged, I'll make follow-up PR for hls & subtitles while I transition kyoo to use this for the web. |
So this is good question 🤔 on mobile we do re-init on source change. So on web I guess with should do something like this ? const [source, setSource] = React.useState(props.source)
useEffect(() => {
setSource(props.source)
}, [props.source])
// and add method to ref WDYT @zoriya ? |
This is assuming that I am fine with this behavior, if we decide to go with this. I'll also add it in the documentation. |
Yeah you're right! but do we have any alternative? (idk if there is, just thinking loudly) |
Maybe we could use |
No, I don't think there's a good alternative available. Something like: const [src, setSource] = useState(source)
const oldSource = useMemo(source);
useEffect(() => {
if (deepEqual(oldSource.current, source))
return;
setSource(source);
oldSource.current = source;
}, [source]);
// add setSource to ref With |
Yeah this looks kinda evil 😅 But I think this will work best, also I would rename |
oh yeah i meant |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much!
@moskalakamil can you look at this and test it? If you will be fine you can merge
Okay, I will check it later today. Thank you so much, @zoriya. Amazing work! |
@zoriya We need to update constants/general.ts in the bare example as well, because the Expo example is overridden in the
|
LGTM! Amazing work @zoriya 🔥 |
@zoriya I misse to thank you for this PR, so Thank you very much ! |
@zoriya I vaguely remember that you mentioned you were planning to work on hls support. I actually have a version of this working, but its kind of sloppy, but I'm wondering if you had made any inroads with that yourself. Might be helpful for us to coordinate. |
I need to fix expo example to merge it (but no idea how to do it for now) |
@zoriya okay interesting. doesn't look like that applies super cleanly on what is there though. What was the reasoning behind using hls.js instead of videojs or shaka? Seems like supporting dash if its possible might be a good thing. |
I personally didn't need more than hls.js, for rnv we would indeed need to consider alternatives before. |
Summary
This adds web support for RNV. It does not include ads, drm, hls or any fancy player options not supported by an HTML5 player. I think HLS.js would be good to have included by default but if we do, it should be in a FU PR.
For now this PR is in a very draft state, I have not yet tested nor updated the documentation. I'll do it in the following hours/days (I'm currently working from my hospital bed, so do not know how much work I'll do soon).
I made this draft mostly to get preliminary feedback on how I approached this.
Closes #2719
Missing steps
Test plan
use this in Kyoo, I took the base implementation from there and the projects needs HLS and custom handling for subtitles for example.Will do after this is merged and we try to add shaka/video.js or something like that.